<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>component std02</title>
	<script src="js/vue.js"></script>
</head>
<body>
	<div id="app">
		<my-component2 v-for="n in 3" :key="n"></my-component2><br>
		<my-component3 v-for="n in 3" :key="n"></my-component3><br>
		<!--<my-component4 ></my-component4><br>-->

		<child message="hello!"></child><br>
		<other-child my-message="hello!"></other-child><br>

		<div>
			<input v-model="parentMsg" />
			<br>
			<other-child v-bind:my-message="parentMsg"></other-child><br>

			<bind-obj v-bind="{title:'span title',text:'span text'}"></bind-obj><br>

			<bind-obj v-bind="objbind"></bind-obj><br>

			<prop-validator class="no-props" v-bind="{propA:1,propB:'test',propC:'pppp',propE:{a:'object'},propF:11}"></prop-validator>

            <div id="counter-event-example">
                <p>{{ total }}</p>
                <button-counter v-on:counter-minus="incrementMinus" v-on:counter-add="incrementAdd" v-on:click.native="incrementAdd" ></button-counter>
                <button-counter v-on:counter-minus="incrementMinus" v-on:counter-add="incrementAdd"></button-counter>
            </div>

            <div>
                <label>{{syncTest}}</label><br><sync-test v-bind:syncprop="syncTest"></sync-test>
            </div>

            <div>
                <currency-input v-model="price"></currency-input>
            </div>
        </div>
	</div>
<script>
    (function () {
            /*'my-component':{
             template: '<span>{{ message }}</span>',
             /!**
             * compontent data 必须定义为function 否则编译异常
             *!/
             data: {
             message: 'hello'
             }
             }*/
            Vue.component('my-component2',{
                template: '<button v-on:click="counter += 1">{{ counter }}</button>',
                        /**
                         * compontent data 必须定义为function 否则编译异常
                         */
                        data: function () {
                    return compontentData;
                }
            });
            Vue.component('my-component3',{
                template: '<button v-on:click="counter += 1">{{ counter }}</button>',
                        /**
                         * compontent data 必须定义为function 否则编译异常
                         */
                        data: function () {
                    return {counter:0};
                }
            });
            /**
             *
             * 父子组件错误示例
             * * /
             /* 'my-component4':{
                template: '<lable>{{counter}}</lable><my-component3></my-component3><br>',
                /!**
                 * compontent data 必须定义为function 否则编译异常
                 *!/
                data: function () {
                    return {counter:0};
                }
            }*/
            Vue.component('child',{
                // 声明 props
                props: ['message'],
                        // 就像 data 一样，prop 也可以在模板中使用
                        // 同样也可以在 vm 实例中通过 this.message 来使用
                        template: '<span>{{ message }}</span>'
            });

            /**
             * html标签和元素不区分大小写，当在组件中定义组件名使用了驼峰标识或元素时在使用时则须改为小写加中划线
             * 如otherChild在使用时要改为other-child
             */
            Vue.component('otherChild',{
                // 声明 props
                props: ['myMessage'],
                        // 就像 data 一样，prop 也可以在模板中使用
                        // 同样也可以在 vm 实例中通过 this.message 来使用
                        template: '<span>{{ myMessage }}</span>'
            });
            Vue.component('bind-obj',{
                // 声明 props
                props: ['title','text'],
                        // 就像 data 一样，prop 也可以在模板中使用
                        // 同样也可以在 vm 实例中通过 this.message 来使用
                        template: '<span v-bind:title="title">{{ text }}</span>'
            });
            Vue.component('prop-validator',{
                // 声明 props
                props: {
                    // 基础类型检测 (`null` 指允许任何类型)
                    propA: Number,
                            // 可能是多种类型
                            propB: [String, Number],
                            // 必传且是字符串
                            propC: {
                        type: String,
                                required: true
                    },
                    // 数值且有默认值
                    propD: {
                        type: Number,
                    default: 100
                    },
                    // 数组/对象的默认值应当由一个工厂函数返回
                    propE: {
                        type: Object,
                    default: function () {
                            return { message: 'hello' }
                        }
                    },
                    // 自定义验证函数
                    propF: {
                        validator: function (value) {
                            return value > 10
                        }
                    }
                },
                /**
                 * 当组件模板中存在多个标签时一定要用一个标签把所有标签包起来作为根节点
                 */
                template: '<div><input v-bind:value="propA"/><input v-bind:value="propB"/><br/><input v-bind:value="propC"/><input v-bind:value="propD"/><br/><input v-bind:value="propE.a"/><input v-bind:value="propF"/></div>'
            });
            Vue.component('button-counter',{
                template: '<div><label>{{ counter }}</label><button v-on:click="counterAdd">+</button><button v-on:click="counterMinus">-</button></div>',
                        data: function () {
                    return {counter: 0}
                },
                methods: {
                    counterAdd: function () {
                        this.counter += 1;
                        this.$emit('counter-add');
                    },
                    counterMinus: function () {
                        this.counter -= 1;
                        this.$emit('counter-minus');
                    }
                },
            });
            Vue.component('sync-test',{
                props:["syncprop"],
                template:'<div><label>{{syncprop}}</label><input v-bind:value="syncprop"/></div>',
            });

            Vue.component('currency-input', {
                template: '<span>$<input ref="input" v-bind:value="value" v-on:input="updateValue($event.target.value)" ></span>',
                props: ['value'],
                methods: {
                    // 不是直接更新值，而是使用此方法来对输入值进行格式化和位数限制
                    updateValue: function (value) {
                        debugger;
                        var formattedValue = value
                        // 删除两侧的空格符
                                .trim()
                                // 保留 2 位小数
                                .slice(
                                        0,
                                        value.indexOf('.') === -1
                                                ? value.length
                                                : value.indexOf('.') + 3
                                )
                        // 如果值尚不合规，则手动覆盖为合规的值
                        if (formattedValue !== value) {
                            this.$refs.input.value = formattedValue
                        }
                        // 通过 input 事件带出数值
                        this.$emit('input', Number(formattedValue))
                    }
                }
            });
        Vue.component('currency-input', {
            template: '\
    <div>\
      <label v-if="label">{{ label }}</label>\
      $\
      <input\
        ref="input"\
        v-bind:value="value"\
        v-on:input="updateValue($event.target.value)"\
        v-on:focus="selectAll"\
        v-on:blur="formatValue"\
      >\
    </div>\
  ',
            props: {
                value: {
                    type: Number,
                    default: 0
                },
                label: {
                    type: String,
                    default: ''
                }
            },
            mounted: function () {
                this.formatValue()
            },
            methods: {
                updateValue: function (value) {
                    var result = currencyValidator.parse(value, this.value)
                    if (result.warning) {
                        this.$refs.input.value = result.value
                    }
                    this.$emit('input', result.value)
                },
                formatValue: function () {
                    this.$refs.input.value = currencyValidator.format(this.value)
                },
                selectAll: function (event) {
                    // Workaround for Safari bug
                    // http://stackoverflow.com/questions/1269722/selecting-text-on-focus-using-jquery-not-working-in-safari-and-chrome
                    setTimeout(function () {
                        event.target.select()
                    }, 0)
                }
            }
        });

    })();

    var compontentData = { counter: 0 }
	new Vue({
		el: '#app',
		data: {
            parentMsg:'this is parent msg!',
            objbind:{title:'span2 title',text:'span2 text'},
            total:0,
            syncTest:'sync test',
            price:'10'
		},
        methods: {
            incrementAdd: function () {
                this.total += 1
            },
            incrementMinus: function () {
                this.total -= 1
            },
        }
	});
</script>
</body>
</html>